import { Menu, Icon, Dropdown, DropdownMenu, DropdownItem } from 'view-design'

const Item = Menu.Item
const SubMenu = Menu.Sub

export default {
  name: 'SMenu',
  props: {
    menu: {
      type: Array,
      required: true
    },
    theme: {
      type: String,
      required: false,
      default: 'dark'
    },
    width: {
      type: String,
      required: false,
      default: 'auto'
    },
    mode: {
      type: String,
      required: false,
      default: 'vertical'
    },
    collapsed: {
      type: Boolean,
      required: false,
      default: false
    }
  },
  data () {
    return {
      openKeys: [],
      selectedKeys: [],
      cachedOpenKeys: [],
      screenWidth: 0,
      limit: 7
    }
  },
  computed: {
    rootSubmenuKeys: vm => {
      const keys = []
      vm.menu.forEach(item => keys.push(item.path))
      return keys
    }
  },
  created () {
    this.updateMenu()
  },
  mounted () {
    const that = this
    // 宽度适应
    that.screenWidth = document.body.clientWidth
    window.onresize = () => {
      return (() => {
        that.screenWidth = document.body.clientWidth
      })()
    }
  },
  watch: {
    collapsed (val) {
      if (val) {
        this.cachedOpenKeys = this.openKeys.concat()
        this.openKeys = []
      } else {
        this.openKeys = this.cachedOpenKeys
      }
    },
    $route: function () {
      this.updateMenu()
    },
    screenWidth (val) {
      const that = this
      if (val <= 860) {
        that.limit = 1
      } else if (val > 860 && val <= 1200) {
        that.limit = 3
      } else {
        that.limit = 6
      }
    }
  },
  methods: {
    renderIcon: function (h, icon) {
      if (icon === 'none' || icon === undefined) {
        return null
      }
      const props = { size: 14 }
      typeof (icon) === 'object' ? props.component = icon : props.type = icon
      return h(Icon, { props: { ...props } })
    },
    /**
     <Dropdown ref="dropdown" @on-click="handleClick" :class="hideTitle ? '' : 'collased-menu-dropdown'" :transfer="hideTitle" :placement="placement">
     <a class="drop-menu-a" type="text" @mouseover="handleMousemove($event, children)" :style="{textAlign: !hideTitle ? 'left' : ''}"><common-icon :size="rootIconSize" :color="textColor" :type="parentItem.icon"/><span class="menu-title" v-if="!hideTitle">{{ showTitle(parentItem) }}</span><Icon style="float: right;" v-if="!hideTitle" type="ios-arrow-forward" :size="16"/></a>
     <DropdownMenu ref="dropdown" slot="list">
     <template v-for="child in children">
     <collapsed-menu v-if="showChildren(child)" :icon-size="iconSize" :parent-item="child" :key="`drop-${child.name}`"></collapsed-menu>
     <DropdownItem v-else :key="`drop-${child.name}`" :name="child.name"><common-icon :size="iconSize" :type="child.icon"/><span class="menu-title">{{ showTitle(child) }}</span></DropdownItem>
     </template>
     </DropdownMenu>
     </Dropdown>
     * @param h
     * @param menu
     * @param pIndex
     * @param index
     * @returns {*}
     */
    renderDropdownMenu: function (h, menu, pIndex, index) {
      const this2_ = this
      const pIndex_ = pIndex + '_' + index
      const icon = h(Icon, { props: { type: menu.meta.icon, size: 18 } })
      const itemArr = []
      if (!menu.hideChildrenInMenu && menu.children && menu.children.length > 0) {
        menu.children.forEach(function (item, i) {
          if (item.children && item.children.length > 0) {
            itemArr.push(this2_.renderDropdownMenu(h, item, pIndex_, i))
          } else {
            const target = item.meta.target || null
            const tag = target && 'a' || 'router-link'
            const props = { to: { name: item.name } }
            const attrs = { href: item.path, target: item.meta.target, class: 'drop-menu-a' }
            itemArr.push(h(DropdownItem, { props: { key: `drop-${item.name}`, name: item.name } },
              [
                h(tag, { props: props, attrs: attrs }, [this2_.renderIcon(h, item.meta.icon), h('span', [item.meta.title])])
              ]))
          }
        })
      }
      return h(Dropdown, { props: { transfer: true, placement: (this.mode === 'vertical' || menu.children.length > 0 ? 'right-start' : ''), transferClassName: 'nav-dropdown-menu' } }, [
        h('a', { attrs: { class: 'nav-drop-menu-a' } }, [icon, pIndex !== '0' ? [h('span', [this2_.collapsed ? '' : menu.meta.title]), this.mode === 'vertical' && this.collapsed ? '' : h(Icon, { props: { type: 'ios-arrow-forward', size: '16' } })] : '']),
        h(DropdownMenu, { props: { ref: 'dropdown' }, slot: 'list' }, itemArr)
      ])
    },
    renderMenuItem: function (h, menu, pIndex, index) {
      const target = menu.meta.target || null
      return h(Item, {
        props: {
          name: menu.name ? menu.name : 'item_' + pIndex + '_' + index,
          to: menu.path,
          target: target
        }
      }, [
        this.renderIcon(h, menu.meta.icon),
        h('span', [menu.meta.title])
      ])
    },
    renderSubMenu: function (h, menu, pIndex, index) {
      const this2_ = this
      const subItem = [h('span', { slot: 'title' }, [this.renderIcon(h, menu.meta.icon), h('span', [menu.meta.title])])]
      const itemArr = []
      const pIndex_ = pIndex + '_' + index
      if (!menu.hideChildrenInMenu && menu.children && menu.children.length > 0) {
        menu.children.forEach(function (item, i) {
          itemArr.push(this2_.renderItem(h, item, pIndex_, i))
        })
      }
      return h(SubMenu, { props: { name: menu.name ? menu.name : 'submenu_' + pIndex + '_' + index } }, subItem.concat(itemArr))
    },
    renderItem: function (h, menu, pIndex, index) {
      if (!menu.hidden) {
        return menu.children && menu.children.length > 0 && !menu.hideChildrenInMenu
          ? (this.$props.collapsed || this.mode === 'horizontal') ? this.renderDropdownMenu(h, menu, pIndex, index) : this.renderSubMenu(h, menu, pIndex, index)
          : this.renderMenuItem(h, menu, pIndex, index)
      }
    },
    renderMenu: function (h, menuTree) {
      const this2_ = this
      const menuArr = []
      menuTree.forEach(function (menu, i) {
        if (!menu.hidden) {
          menuArr.push(this2_.renderItem(h, menu, i, i))
        }
      })
      return menuArr
    },
    onOpenChange (openKeys) {
      // 在水平模式下时执行，并且不再执行后续
      if (this.mode === 'horizontal') {
        this.openKeys = openKeys
        return
      }
      // 非水平模式时
      const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key))
      if (!this.rootSubmenuKeys.includes(latestOpenKey)) {
        this.openKeys = openKeys
      } else {
        this.openKeys = latestOpenKey ? [latestOpenKey] : []
      }
    },
    updateMenu () {
      const routes = this.$route.matched.concat()
      const { hidden } = this.$route.meta
      if (routes.length >= 3 && hidden) {
        routes.pop()
        this.selectedKeys = [routes[routes.length - 1].path]
      } else {
        this.selectedKeys = [routes.pop().path]
      }
      const openKeys = []
      if (this.mode === 'vertical') {
        routes.forEach(item => {
          openKeys.push(item.path)
        })
      }

      this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys)
    }
  },
  render (h) {
    const { mode, theme, openKeys, selectedKeys, limit, collapsed, width } = this
    let menu = this.menu
    if (mode === 'horizontal' && menu.length >= limit) {
      // 水平菜单 长度截取
      const newmenu = menu.slice(0, limit)
      newmenu.push({ menuId: 'more', parentId: '0', menuName: '', meta: { icon: 'ios-more', title: '' }, children: menu.slice(limit) })
      menu = newmenu
    }
    return h(
      Menu,
      {
        props: {
          width: width,
          accordion: true,
          theme: theme,
          mode: mode,
          openNames: openKeys,
          selectedKeys: selectedKeys
        },
        on: {
          'on-open-change': this.onOpenChange,
          'on-select': obj => {
            this.selectedKeys = obj.selectedKeys
            this.$emit('select', obj)
          }
        }
      },
      this.renderMenu(h, menu)
    )
  }
}
